/**
* @author Ashish Gupta
* CVSSP, University of Surrey
* Copyright (c) 2010 Ashish Gupta
* All rights reserved.
*/
/**
 * 
 */
package classification;

import image.ImageSet;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import weka.core.Instances;

/**
 * @author Ashish
 *
 */
public class VisualCodebook implements Codebook2Classifier {
	private ArrayList<ArrayList<Double>> visualCodebook = new ArrayList<ArrayList<Double>>();
	private Double[] positiveHistogram = null;
	private Double[] negativeHistogram = null;
	/**
	 * @param codebook the codebook to set
	 * @param imageSet
	 */
	public void setCodebook(ImageSet imageSet) {
		for(int i=0;i<imageSet.getImages().size();i++){
			ArrayList<Double> cbvector = new ArrayList<Double>();
			cbvector.add(imageSet.getImages().get(i).getClassLabel());
			cbvector.addAll(imageSet.getImages().get(i).getHistogram());
			this.visualCodebook.add(cbvector );
		}
	}
	
	public void incrementCodebook(int row, int col){
		Double newVal = visualCodebook.get(row).get(col)+1;
		visualCodebook.get(row).set(col, newVal);
	}

	/**
	 * @return the codebook
	 */
	public ArrayList<ArrayList<Double>> getCodebook() {
		return visualCodebook;
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toARFFfile(java.io.File)
	 */
	@Override
	public void toARFFfile(String fileURI) throws IOException {
		File arffFile = new File(fileURI);
		FileWriter fw = new FileWriter(arffFile);
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write("@RELATION visualcategory" + "\n");
		for(int i=0;i<this.visualCodebook.get(0).size();i++){
			bw.write("@ATTRIBUTE " + i + " NUMERIC" + "\n");
		}
		bw.write("@ATTRIBUTE" + " class " + "{positive,negative}" + "\n");
		bw.write("@DATA" + "\n");
		for(int i=0;i<this.visualCodebook.size();i++){
			for(int j=1;j<this.visualCodebook.get(i).size();j++){//note j starts from 1 instead of 0
				bw.write(this.visualCodebook.get(i).get(j) + ",");
			}

			if(this.visualCodebook.get(i).get(0) == 1){
				bw.write("positive" + "\n");
			}
			else{
				bw.write("negative" + "\n");
			}
		}
		bw.close();
		fw.close();
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toCSVfile(java.io.File)
	 */
	@Override
	public void toCSVfile(String codebookCSVFilename) throws IOException {
		File codebookCSV = new File(codebookCSVFilename);
		FileWriter fw = new FileWriter(codebookCSV);
		BufferedWriter bw = new BufferedWriter(fw);
		for(int i=0;i<this.visualCodebook.size();i++){
			for(int j=1;j<this.visualCodebook.get(i).size();j++){//note j starts from 1 instead of 0
				bw.write(this.visualCodebook.get(i).get(j) + ",");
			}
			if(this.visualCodebook.get(i).get(0) == 1){
				bw.write("positive" + "\n");
			}
			else{
				bw.write("negative" + "\n");
			}
		}
		bw.close();
		fw.close();
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toFile(java.io.File)
	 */
	@Override
	public File toFile(String fileURI) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see classification.Codebook2Classifier#toInstances()
	 */
	@Override
	public Instances toInstances() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @param positiveHistogram the positiveHistogram to set
	 */
	public void calcPositiveHistogram() {
		this.positiveHistogram = new Double[this.visualCodebook.get(0).size()-1];
		Iterator<ArrayList<Double>> itr = this.visualCodebook.iterator();
		while(itr.hasNext()){
			ArrayList<Double> histogram = itr.next();
			if(histogram.get(0) == 1){ // category symbol literal to be changed to category symbol
				for(int i = 1; i < histogram.size(); i++){
					positiveHistogram[i-1]+=histogram.get(i);
				}
			}
		}
	}

	

	/**
	 * @param negativeHistogram the negativeHistogram to set
	 */
	public void calcNegativeHistogram() {
		this.negativeHistogram = new Double[this.visualCodebook.get(0).size()];
		Iterator<ArrayList<Double>> itr = this.visualCodebook.iterator();
		while(itr.hasNext()){
			ArrayList<Double> histogram = itr.next();
			if(histogram.get(0) == -1){
				for(int i=1;i<histogram.size();i++){
					negativeHistogram[i-1]+=histogram.get(i);
				}
			}
		}
	}

	/**
	 * @param positiveHistogram the positiveHistogram to set
	 */
	public void setPositiveHistogram(Double[] positiveHistogram) {
		this.positiveHistogram = positiveHistogram;
	}

	/**
	 * @return the positiveHistogram
	 */
	public Double[] getPositiveHistogram() {
		return positiveHistogram;
	}

	/**
	 * @param negativeHistogram the negativeHistogram to set
	 */
	public void setNegativeHistogram(Double[] negativeHistogram) {
		this.negativeHistogram = negativeHistogram;
	}

	/**
	 * @return the negativeHistogram
	 */
	public Double[] getNegativeHistogram() {
		return negativeHistogram;
	}

	
	
	

}
